#include <cjson/cJSON.h>

#include "../util.h"
#include "onlineinfo.h"

action_onlineinfo_result action_onlineinfo(
    const char* bind_interface,
    const char* portal_host,
    const char* user_index
) {
    action_onlineinfo_result result = {
        ACTION_FETCHED_SUCCESSFULLY,
        SUCCESS,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL
    };
    
    const char* addr_strs[] = {
        "http://",
        portal_host,
        "/eportal/InterFace.do?method=getOnlineUserInfo",
        NULL
    };
    char* address = string_concat(addr_strs);
    
    const char* post_strs[] = {
        "userIndex=",
        user_index == NULL ? NULL : url_encode_component(user_index),
        NULL
    };
    char* post_string = string_concat(post_strs);
    if (post_strs[1] != NULL) {
        free((char*) post_strs[1]);
    }
    
    CURL_EASY_SETUP({
        // setup action
        curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, post_string);
        curl_common_setup(curl, portal_host, "");
        free(post_string);
    }, {
        cJSON* onlineinfo = cJSON_Parse(chunk.memory);
        if (onlineinfo == NULL) {
            goto failure;
        }
        
        const cJSON* return_status;
        const cJSON* message;
        const cJSON* user_id;
        const cJSON* user_name;
        const cJSON* user_ip;
        const cJSON* user_mac;
        const cJSON* user_package;
        const cJSON* user_index;
        
        return_status = cJSON_GetObjectItemCaseSensitive(onlineinfo, "result");
        if (cJSON_IsString(return_status) && (return_status -> valuestring != NULL)) {
            if (strcmp(return_status -> valuestring, "success") == 0) {
                result.return_status = SUCCESS;
            } else if (strcmp(return_status -> valuestring, "fail") == 0) {
                result.return_status = FAILED;
            } else if (strcmp(return_status -> valuestring, "wait") == 0) {
                result.return_status = WAIT;
            } else {
                goto failure;
            } 
        } else {
            goto failure;
        }
        
        message = cJSON_GetObjectItemCaseSensitive(onlineinfo, "message");
        if (cJSON_IsString(message) && (message -> valuestring != NULL)) {
            result.message = string_duplicate(message -> valuestring);
        } else {
            goto failure;
        }
        
        if (result.return_status != SUCCESS) {
            goto end;
        }
        
        user_id = cJSON_GetObjectItemCaseSensitive(onlineinfo, "userId");
        if (cJSON_IsString(user_id) && (user_id -> valuestring != NULL)) {
            result.user_id = string_duplicate(user_id -> valuestring);
        } else {
            goto failure;
        }
        
        user_name = cJSON_GetObjectItemCaseSensitive(onlineinfo, "userName");
        if (cJSON_IsString(user_name) && (user_name -> valuestring != NULL)) {
            result.user_name = string_duplicate(user_name -> valuestring);
        } else {
            goto failure;
        }
        
        user_ip = cJSON_GetObjectItemCaseSensitive(onlineinfo, "userIp");
        if (cJSON_IsString(user_ip) && (user_ip -> valuestring != NULL)) {
            result.user_ip = string_duplicate(user_ip -> valuestring);
        } else {
            goto failure;
        }
        
        user_mac = cJSON_GetObjectItemCaseSensitive(onlineinfo, "userMac");
        if (cJSON_IsString(user_mac) && (user_mac -> valuestring != NULL)) {
            result.user_mac = string_duplicate(user_mac -> valuestring);
        } else {
            goto failure;
        }
        
        user_package = cJSON_GetObjectItemCaseSensitive(onlineinfo, "userPackage");
        if (cJSON_IsString(user_package) && (user_package -> valuestring != NULL)) {
            result.user_package = string_duplicate(user_package -> valuestring);
        } else {
            goto failure;
        }
        
        user_index = cJSON_GetObjectItemCaseSensitive(onlineinfo, "userIndex");
        if (cJSON_IsString(user_index) && (user_index -> valuestring != NULL)) {
            result.user_index = string_duplicate(user_index -> valuestring);
        } else {
            goto failure;
        }
        
        end:
        free(address);
        return result;
        
        failure:
        result.status = ACTION_PARSE_FAILURE;
        goto end;
    }, {
        // failure action
        result.status = ACTION_FETCHING_FAILURE;
        free(address);
        return result;
    }, address, bind_interface, 8192);
}
